package tool.codescan.loggers;

import java.util.List;

import tool.data.AbstractClassEntity;
import tool.data.ConcreteClassEntity;
import tool.data.InterfaceEntity;
import tool.data.ResultStore;
import tool.data.TypeDefinition;

	/**
	 * @author jwb09119
	 * @date 2013/11/11
	 * 
	 * This class stores the various data collected by visitors and collates it as required.
	 * Note that the information stored here is primarily about the incidence of Types.
	 *
	 */

public class InterfaceAndClassLogger {
		
		private ResultStore results;
		
		
		// Constructor
		public InterfaceAndClassLogger (ResultStore results) {
			
			this.results = results;
			
		}
		
		
		/**
		 * @param name - the name of the Interface
		 * @param packageName - the package that contains the interface
		 * @param interfaceTypes - a list of strings representing interfaces implemented by name.
		 * 
		 * Log the existence of an interface
		 */
		public void logInterface(TypeDefinition type, List<TypeDefinition> interfaceTypes,
																	List<TypeDefinition> extendsTypes) {
			
			String key = type.getNameWithPath();
			
			if (results.interfaceExists(key)) {
				
				throw new RuntimeException("Duplicate Java Entity Parsed (" +key+ ")");
			
			} else {
				
				results.addInterface(key, new InterfaceEntity(type, interfaceTypes, extendsTypes));
				
			}
			
		}

		
		/**
		 * @param name - the name of the abstract class
		 * @param packageName - the package that contains the abstract class
		 * @param interfaceTypes - a list of strings representing interfaces implemented by name.
		 * 
		 * Log the existence of an abstract class
		 */
		public void logAbstractClass(TypeDefinition type, List<TypeDefinition> interfaceTypes,
																	List<TypeDefinition> extendsTypes) {

			String key = type.getNameWithPath();
			
			if (results.abstractClassExists(key)) {
				
				throw new RuntimeException("Duplicate Java Entity Parsed (" +key+ ")");
			
			} else {
				
				results.addAbstractClass(key, 
						new AbstractClassEntity(type, interfaceTypes, extendsTypes));
				
			}
			
		}
		
		
		/**
		 * @param name - the name of the concrete class
		 * @param packageName - the package that contains the concrete class
		 * @param interfaceTypes - a list of strings representing interfaces implemented by name.
		 * 
		 * Log the existence of a concrete class
		 */
		public void logClass(TypeDefinition type, List<TypeDefinition> interfaceTypes,
																	List<TypeDefinition> extendsTypes) {

			String key = type.getNameWithPath();
			
			if (results.classExists(key)) {
				
				throw new RuntimeException("Duplicate Java Entity Parsed (" +key+ ")");
			
			} else {
				
				results.addClass(key, new ConcreteClassEntity(type, interfaceTypes, extendsTypes));
				
			}
			
		}


        public void logInnerClass (String innerClassName, TypeDefinition containingClass) {

            results.addInnerClass(innerClassName, containingClass);
            
        }


}
